//********************************************************************
// 
//  file:  StoredFile.cs
// 
//  (C) Copyright 2010, Diomede Corporation
//  All rights reserved
// 
//  Use, modification, and distribution is subject to   
//  the New BSD License (See accompanying file license.txt).
// 
//********************************************************************

using System;
using System.Collections.Generic;
using data.diomedestorage.com;
using Diomede.SDK.Enums;

namespace Diomede.SDK
{

    #region Interfaces

    /// <summary>
    /// Provide interface for Diomede Storage StoreFiles
    /// </summary>
    public interface IStoredFile
    {
        /// <summary>
        /// Holds the parent session of the StoreFile.
        /// </summary>
        ISession Session { get; set; }

        /// <summary>
        /// StoredFile's id
        /// </summary>
        long? FileId { get; set; }

        /// <summary>
        /// Will get the StoredFile's download Url.
        /// </summary>
        /// <param name="maximumDownloads">The number of downloads before the Url will expire.  If set to null no dowload limit will be applied.</param>
        /// <param name="lifetimeHours">The time before the download url will expire.  If null download Url will not expire.</param>
        /// <param name="maximumUniqueIP">The number of unique IP that the download Url will allow.  If set to null unique IP will be unlimited.</param>
        /// <param name="errorUrl">The Url that the system will redirect, if the Url is already expired or invalid.  If not provide and String.Empty will be returned.</param>
        /// <returns>Will return Url if command is successful, or <see cref="string.Empty">String.Empty</see> if not.</returns>
        /// <example>
        /// <code>
        /// void getDownloadUrl()
        /// {
        ///     ISession session = new Session();
        ///     if (session.Login("username", "password").Status != Enums.ExecutionResults.Success)
        ///     {
        ///         Console.WriteLine(string.Format("Failed to login to Diomede service."));
        ///         return;
        ///     }
        /// 
        ///     int fileId = 15; //sample file id
        ///     IFileManagement fileMgr = session as IFileManagement;
        ///     //create session instance of the file
        ///     IStoredFile file = fileMgr.StoredFileInstance(fileId);
        /// 
        ///     //get the download url
        ///     string url = file.GetDownloadUrl(5, null, null, "http://mydomain.com/error.aspx");
        ///     //check if the return url is empty
        ///     if (!string.IsNullOrEmpty(url))
        ///     {
        ///         Console.WriteLine(string.Format("Download url is {0}", url));
        ///     }
        /// }
        /// 
        /// </code>
        /// <code lang="VB.NET">
        /// Shared Sub GetDownloadUrl()
        ///     'create new session
        ///     Dim session As ISession = New Session()
        ///     If Not (session.Login("username", "password").Status = Enums.ExecutionResults.Success) Then
        ///         Console.WriteLine(String.Format("Failed to login to Diomede service."))
        ///         Return
        ///     End If
        ///     'sample file id
        ///     Dim fileId As Integer = 15
        ///     Dim fileMgr As IFileManagement = session
        ///     'create session instance of the file
        ///     Dim file As IStoredFile = fileMgr.StoredFileInstance(fileId)
        ///     'get the download url
        ///     Dim url As String = file.GetDownloadUrl(5, Nothing, Nothing, "http://mydomain.com/error.aspx")
        ///     If (Not String.IsNullOrEmpty(url)) Then
        ///         Console.WriteLine(String.Format("Download url is {0}", url))
        ///     End If
        /// End Sub
        ///
        /// </code>
        /// </example>
        string GetDownloadUrl(Nullable<int> maximumDownloads, Nullable<int> lifetimeHours, Nullable<int> maximumUniqueIP,
                              string errorUrl);

        /// <summary>
        /// Will Undelete a deleted file.
        /// </summary>
        /// <returns>will return Status = Success if command is successful.</returns>
        /// <example>
        /// <code>
        /// ISession session = new Session();
        ///     if (session.Login("username", "password").Status != Enums.ExecutionResults.Success)
        ///     {
        ///         Console.WriteLine(string.Format("Failed to login to Diomede service."));
        ///         return;
        ///     }
        /// 
        ///     int fileId = 15; //sample file id
        ///     IFileManagement fileMgr = session as IFileManagement;
        ///     //create session instance of the file
        ///     IStoredFile file = fileMgr.StoredFileInstance(fileId);
        /// 
        ///     //delete the file
        ///     IStoredFileExecResult result;
        ///     //delete the file
        ///     result = file.Delete();
        ///     if (result.Status == Diomede.SDK.Enums.ExecutionResults.Success)
        ///     {
        ///         Console.WriteLine("File successfully deleted.");
        ///         //undelete the file
        ///         result = file.Undelete();
        ///         if (result.Status == Diomede.SDK.Enums.ExecutionResults.Success)
        ///             Console.WriteLine("File is successfully undeleted.");
        ///     }
        /// </code>
        /// <code lang="VB.NET">
        /// 'create new session
        /// Dim session As ISession = New Session()
        /// If Not (session.Login("username", "password").Status = Enums.ExecutionResults.Success) Then
        ///     Console.WriteLine(String.Format("Failed to login to Diomede service."))
        ///     Return
        /// End If
        /// 'sample file id
        /// Dim fileId As Integer = 15
        /// Dim fileMgr As IFileManagement = session
        /// 'create session instance of the file
        /// Dim file As IStoredFile = fileMgr.StoredFileInstance(fileId)
        /// Dim result As IStoredFileExecResult
        /// 'delete the file
        /// result = file.Delete()
        /// If result.Status = Enums.ExecutionResults.Success Then
        ///     Console.WriteLine("File successfully deleted.")
        ///     'undelete the file
        ///     result = file.Undelete()
        ///     If (result.Status = Enums.ExecutionResults.Success) Then
        ///         Console.WriteLine("File is successfully undeleted.")
        ///     End If
        /// End If
        /// </code>
        /// </example>
        IStoredFileExecResult Undelete();

        /// <summary>
        /// Will Delete a file.
        /// </summary>
        /// <returns>will return Status = Success if command is successful.</returns>
        /// <example>
        /// <code>
        /// ISession session = new Session();
        ///     if (session.Login("username", "password").Status != Enums.ExecutionResults.Success)
        ///     {
        ///         Console.WriteLine(string.Format("Failed to login to Diomede service."));
        ///         return;
        ///     }
        /// 
        ///     int fileId = 15; //sample file id
        ///     IFileManagement fileMgr = session as IFileManagement;
        ///     //create session instance of the file
        ///     IStoredFile file = fileMgr.StoredFileInstance(fileId);
        /// 
        ///     //delete the file
        ///     IStoredFileExecResult result;
        ///     //delete the file
        ///     result = file.Delete();
        ///     if (result.Status == Diomede.SDK.Enums.ExecutionResults.Success)
        ///     {
        ///         Console.WriteLine("File successfully deleted.");
        ///         //undelete the file
        ///         result = file.Undelete();
        ///         if (result.Status == Diomede.SDK.Enums.ExecutionResults.Success)
        ///             Console.WriteLine("File is successfully undeleted.");
        ///     }
        /// </code>
        /// <code lang="VB.NET">
        /// 'create new session
        /// Dim session As ISession = New Session()
        /// If Not (session.Login("username", "password").Status = Enums.ExecutionResults.Success) Then
        ///     Console.WriteLine(String.Format("Failed to login to Diomede service."))
        ///     Return
        /// End If
        /// 'sample file id
        /// Dim fileId As Integer = 15
        /// Dim fileMgr As IFileManagement = session
        /// 'create session instance of the file
        /// Dim file As IStoredFile = fileMgr.StoredFileInstance(fileId)
        /// Dim result As IStoredFileExecResult
        /// 'delete the file
        /// result = file.Delete()
        /// If result.Status = Enums.ExecutionResults.Success Then
        ///     Console.WriteLine("File successfully deleted.")
        ///     'undelete the file
        ///     result = file.Undelete()
        ///     If (result.Status = Enums.ExecutionResults.Success) Then
        ///         Console.WriteLine("File is successfully undeleted.")
        ///     End If
        /// End If
        /// </code>
        /// </example>
        IStoredFileExecResult Delete();

        /// <summary>
        /// Will rename a file
        /// </summary>
        /// <param name="newName">The new file name.</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IStoredFileExecResult Rename(string newName);

        /// <summary>
        /// Get all available storage types
        /// </summary>
        /// <returns>will return Status = Success if command is successful.</returns>
        IGetStorageTypesExecResult GetStorageTypes();

        /// <summary>
        /// Will replicate a file
        /// </summary>
        /// <param name="fileId">ID of the logical file.</param>
        /// <param name="storageType">Type of storage to store the backup file to.</param>
        /// <param name="expirationDate">After this date, the copy of this file will be discarded.</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IReplicateExecResult Replicate(long fileId, byte storageType, DateTime? expirationDate);

        /// <summary>
        /// Will delete a copy of a file
        /// </summary>
        /// <param name="phyFileId">ID of the copy of the physical file.</param>
        IStoredFileExecResult Unreplicate(long phyFileId);

        /// <summary>
        /// Get the replication information of a file
        /// </summary>
        /// <returns>will return Status = Success if command is successful.</returns>
        IGetPhysicalFilesExecResult GetPhysicalFiles();

        /// <summary>
        /// Will move the file to another <see cref="Enums.StorageTiers">tier</see>.
        /// </summary>
        /// <param name="tier">Storage tier where to move the file.</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IStoredFileExecResult MoveToTier(StorageInfo tier);

        /// <summary>
        /// Will add a meta data to a file.
        /// </summary>
        /// <param name="name">Meta name.</param>
        /// <param name="value">Meta value.</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IAddMetaDataExecResult AddMetaData(string name, string value);

        IAddMetaDataExecResult AddMetaData(int metaDataId);

        IRemoveMetaDataExecResult RemoveMetaData(int metaDataId);

        /// <summary>
        /// List of the file's metadata.
        /// </summary>
        List<MetaData> MetaData { get;}

        ///<summary>
        /// The information of the file.
        ///</summary>
        FileProperties FileInformation { get; set; }
    }


    /// <summary>
    /// Provide interface for StoredFile execution result.
    /// </summary>
    public interface IStoredFileExecResult : IExecResult
    {
    }

    public interface IReplicateExecResult : IExecResult
    {
        long PhyFileID { get; set;}
    }

    public interface IGetPhysicalFilesExecResult : IExecResult
    {
        IList<PhysicalFileInfo> PhysicalFiles { get; set;}
    }

    public interface IGetStorageTypesExecResult : IExecResult
    {
        IList<StorageType> StorageTypes { get; set; }
    }

    public interface IAddMetaDataExecResult : IExecResult
    {
        int MetaDataID{get; set;} 
    }

    public interface IUpdateMetaDataExecResult : IExecResult
    { 
    }

    public interface IDeleteMetaDataExecResult : IExecResult
    { 
    }

    public interface IRemoveMetaDataExecResult : IExecResult
    { 
    }

    #endregion

    #region implementation

    /// <summary>
    /// IStoredFile implementation, see <see cref="IStoredFile"/> for more information.
    /// </summary>
    public class StoredFile : IStoredFile
    {
        /// <summary>
        /// Default constructor.
        /// </summary>
        public StoredFile()
        {
        }

        /// <summary>
        /// Constructor that will accept a file id as a parameter.
        /// </summary>
        /// <param name="fileId">The file id</param>
        public StoredFile(long fileId)
        {
            this.fileId = fileId;
        }

        /// <summary>
        /// Constructor that will accept <see cref="ISession"/> as parameter.
        /// </summary>
        /// <param name="session">The active session.</param>
        public StoredFile(ISession session)
        {
            this.session = session;
        }

        /// <summary>
        /// Constructor that will accept FileProperties as parameter.
        /// </summary>
        /// <param name="fileInfo">File property</param>
        public StoredFile(FileProperties fileInfo)
        {
            this.fileInfo = fileInfo;
            fileId = this.fileInfo.fileID;
        }

        #region IStoredFile Members

        private ISession session;

        /// <summary>
        /// IStoredFile.Session implementation, see <see cref="IStoredFile.Session"/> for more information.
        /// </summary>
        ISession IStoredFile.Session
        {
            get { return session; }
            set { session = value; }
        }

        private long? fileId;

        /// <summary>
        /// IStoredFile.FileId implementation, see <see cref="IStoredFile.FileId"/> for more information.
        /// </summary>
        long? IStoredFile.FileId
        {
            get { return fileId; }
            set { fileId = value; }
        }

        /// <summary>
        /// IStoredFile.GetDownloadUrl implementation, see <see cref="IStoredFile.GetDownloadUrl"/> for more information.
        /// </summary>
        /// <param name="maximumDownloads">Maximum downloads allowed.</param>
        /// <param name="lifetimeHours">Hours before Url expire.</param>
        /// <param name="maximumUniqueIP">Maximum unique IP allowed.</param>
        /// <param name="errorUrl">Url to redirect.</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        string IStoredFile.GetDownloadUrl(Nullable<int> maximumDownloads, Nullable<int> lifetimeHours,
                                          Nullable<int> maximumUniqueIP, string errorUrl)
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return string.Empty;
            if (fileId == null)
                return string.Empty;

            try
            {
                return
                    session.ServiceClient.GetDownloadURL(session.Token, (int)fileId.Value, maximumDownloads, lifetimeHours,
                                                         maximumUniqueIP, errorUrl);
            }
            catch
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// IStoredFile.Undelete implementation, see <see cref="IStoredFile.Undelete"/> for more information.
        /// </summary>
        /// <returns>Will return Status = Success if command is successful.</returns>
        IStoredFileExecResult IStoredFile.Undelete()
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new StoredFileExecResult(ExecutionResults.Failed, "No active session.");
            if (fileId == null)
                return new StoredFileExecResult(ExecutionResults.Failed, "No file to process.");

            try
            {
                session.ServiceClient.UndeleteFile(session.Token, (int)fileId.Value);
                return new StoredFileExecResult(ExecutionResults.Success, "Undelete successful.");
            }
            catch (Exception ex)
            {
                return new StoredFileExecResult(ex);
            }
        }

        /// <summary>
        /// IStoredFile.Delete implementation, see <see cref="IStoredFile.Delete"/> for more information.
        /// </summary>
        /// <returns>will return Status = Success if command is successful.</returns>
        IStoredFileExecResult IStoredFile.Delete()
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new StoredFileExecResult(ExecutionResults.Failed, "No active session.");
            if (fileId == null)
                return new StoredFileExecResult(ExecutionResults.Failed, "No file to process.");

            try
            {
                session.ServiceClient.DeleteFile(session.Token,fileId.Value);
                return new StoredFileExecResult(ExecutionResults.Success, "Delete successful.");
            }
            catch (Exception ex)
            {
                return new StoredFileExecResult(ex);
            }
        }

        /// <summary>
        /// IStoredFile.Rename implementation, see <see cref="IStoredFile.Rename"/> for more information.
        /// </summary>
        /// <param name="newName">New filename</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IStoredFileExecResult IStoredFile.Rename(string newName)
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new StoredFileExecResult(ExecutionResults.Failed, "No active session.");
            if (fileId == null)
                return new StoredFileExecResult(ExecutionResults.Failed, "No file to process.");

            try
            {
                session.ServiceClient.RenameFile(session.Token, fileId.Value, newName);
                return new StoredFileExecResult(ExecutionResults.Success, "Rename successful.");
            }
            catch (Exception ex)
            {
                return new StoredFileExecResult(ex);
            }
        }

        /// <summary>
        /// IStoredFile.Replicate implementation, see <see cref="IStoredFile.Replicate"/> for more information.
        /// </summary>
        /// <param name="fileId">ID of the logical file.</param>
        /// <param name="storageType">Type of storage to store the backup file to.</param>
        /// <param name="expirationDate">After this date, the copy of this file will be discarded.</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IReplicateExecResult IStoredFile.Replicate(long fileId, byte storageType, DateTime? expirationDate)
        {
            this.fileId = fileId;

            if (session == null || string.IsNullOrEmpty(session.Token))
                return new ReplicateExecResult(new Exception("No active session."));
            if (this.fileId == null)
                return new ReplicateExecResult(new Exception("No file to process."));

            try
            {
                long phyFileId = session.ServiceClient.ReplicateFile(session.Token, fileId, storageType, expirationDate);
                return new ReplicateExecResult(phyFileId);
            }
            catch (Exception ex)
            {
                return new ReplicateExecResult(ex);
            }
        }

        /// <summary>
        /// IStoredFile.Unreplicate implementation, see <see cref="IStoredFile.Unreplicate"/> for more information.
        /// </summary>
        /// <param name="phyFileId">ID of the copy of the physical file.</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IStoredFileExecResult IStoredFile.Unreplicate(long phyFileId)
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new StoredFileExecResult(ExecutionResults.Failed, "No active session.");
            if (fileId == null)
                return new StoredFileExecResult(ExecutionResults.Failed, "No file to process.");

            try
            {
                session.ServiceClient.UnreplicateFile(session.Token, phyFileId);
                return new StoredFileExecResult(ExecutionResults.Success, "Unreplicate successful.");
            }
            catch (Exception ex)
            {
                return new StoredFileExecResult(ex);
            }
        }

        /// <summary>
        /// IStoredFile.GetReplicationInfo implementation, see <see cref="IStoredFile.GetReplicationInfo"/> for more information.
        /// </summary>
        IGetPhysicalFilesExecResult IStoredFile.GetPhysicalFiles()
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new GetPhysicalFilesExecResult(new Exception("No active session."));
            if (this.fileId == null)
                return new GetPhysicalFilesExecResult(new Exception("No file to process."));

            try
            {
                PhysicalFileInfo[] files = session.ServiceClient.GetPhysicalFiles(session.Token, fileId.Value);
                IList<PhysicalFileInfo> list = new List<PhysicalFileInfo>();
                foreach (PhysicalFileInfo file in files)
                {
                    list.Add(file);
                }

                return new GetPhysicalFilesExecResult(list);
            }
            catch (Exception ex)
            {
                return new GetPhysicalFilesExecResult(ex);
            }
        }

        /// <summary>
        /// IStoredFile.GetStorageTypes implementation, see <see cref="IStoredFile.GetStorageTypes"/> for more information.
        /// </summary>
        IGetStorageTypesExecResult IStoredFile.GetStorageTypes()
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new GetStorageTypesExecResult(new Exception("No active session."));
            if (this.fileId == null)
                return new GetStorageTypesExecResult(new Exception("No file to process."));

            try
            {
                StorageType[] storageTypes = session.ServiceClient.GetStorageTypes();
                IList<StorageType> list = new List<StorageType>();
                foreach (StorageType storageType in storageTypes)
                {
                    list.Add(storageType);
                }

                return new GetStorageTypesExecResult(list);
            }
            catch (Exception ex)
            {
                return new GetStorageTypesExecResult(ex);
            }
        }

        /// <summary>
        /// IStoredFile.MoveToTier implementation, see <see cref="IStoredFile.MoveToTier"/> for more information.
        /// </summary>
        /// <param name="tier">Destination tier</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IStoredFileExecResult IStoredFile.MoveToTier(StorageInfo tier)
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new StoredFileExecResult(ExecutionResults.Failed, "No active session.");
            if (fileId == null)
                return new StoredFileExecResult(ExecutionResults.Failed, "No file to process.");

            try
            {
                session.ServiceClient.MoveFileToTier(session.Token, (int)fileId.Value, (int) tier, "");
                return new StoredFileExecResult(ExecutionResults.Success, "Move successful.");
            }
            catch (Exception ex)
            {
                return new StoredFileExecResult(ex);
            }
        }

        /// <summary>
        /// IStoredFile.AddMetaData implementation, see <see cref="IStoredFile.AddMetaData(string, object)"/> for more information.
        /// </summary>
        /// <param name="name">Meta name.</param>
        /// <param name="value">Meta value.</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IAddMetaDataExecResult IStoredFile.AddMetaData(string name, string value)
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new AddMetaDataExecResult(new Exception("No active session."));
            if (fileId == null)
                return new AddMetaDataExecResult(new Exception("No file to process."));
            try
            {
                int mId =  session.ServiceClient.CreateFileMetaData(session.Token, fileId.GetValueOrDefault(), name, value);
                return new AddMetaDataExecResult(mId);
            }
            catch (Exception ex)
            {
                return new AddMetaDataExecResult(ex);
            }
        }

        /// <summary>
        /// IStoredFile.AddMetaData implementation, see <see cref="IStoredFile.AddMetaData(IMetaData)"/> for more information.
        /// </summary>
        /// <param name="meta">Meta data.</param>
        /// <returns>will return Status = Success if command is successful.</returns>
        IAddMetaDataExecResult IStoredFile.AddMetaData(int metaDataId)
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new AddMetaDataExecResult(new Exception("No active session."));
            if (fileId == null)
                return new AddMetaDataExecResult(new Exception("No file to process."));
            try
            {
                session.ServiceClient.SetFileMetaData(session.Token, fileId.GetValueOrDefault(), metaDataId);
                return new AddMetaDataExecResult(metaDataId);
            }
            catch (Exception ex)
            {
                return new AddMetaDataExecResult(ex);
            }
        }

        IRemoveMetaDataExecResult IStoredFile.RemoveMetaData(int metaDataId)
        {
            if (session == null || string.IsNullOrEmpty(session.Token))
                return new RemoveMetaDataExecResult(new Exception("No active session."));
            if (fileId == null)
                return new RemoveMetaDataExecResult(new Exception("No file to process."));

            try
            {
                session.ServiceClient.DeleteFileMetaData(session.Token, fileId.GetValueOrDefault(), metaDataId);
                return new RemoveMetaDataExecResult("Remove metadata successful.");
            }
            catch (Exception ex)
            {
                return new RemoveMetaDataExecResult(ex);
            }
        }

        private List<MetaData> metaData;

        /// <summary>
        /// IStoredFile.MetaData implementation, see <see cref="IStoredFile.MetaData"/> for more information.
        /// </summary>
        List<MetaData> IStoredFile.MetaData
        {
            get 
            {
                if (session == null || string.IsNullOrEmpty(session.Token))
                    return null;
                if (fileId == null)
                    return null;

                try
                {
                    metaData = new List<MetaData>(session.ServiceClient.GetFileMetaData(session.Token, fileId.GetValueOrDefault()));
                    foreach (MetaData md in metaData)
                    {
                        md.Session = session;
                    }

                    return metaData;

                }
                catch
                {
                    return null;
                }
            }
        }

        private FileProperties fileInfo;

        /// <summary>
        /// IStoredFile.FileInformation implementation, see <see cref="IStoredFile.FileInformation"/> for more information.
        /// </summary>
        FileProperties IStoredFile.FileInformation
        {
            get { return fileInfo; }
            set
            {
                fileInfo = value;
                fileId = fileInfo.fileID;
            }
        }

        #endregion
    }

    /// <summary>
    /// IStoredFileExecResult implementation, see <see cref="IStoredFileExecResult"/> for more information.
    /// </summary>
    public class StoredFileExecResult : IStoredFileExecResult
    {
        /// <summary>
        /// Default constructor
        /// </summary>
        public StoredFileExecResult()
        {
        }

        /// <summary>
        /// Object constructor that will accept status, and message parameters.
        /// </summary>
        /// <param name="status">Result status.</param>
        /// <param name="message">Result message.</param>
        public StoredFileExecResult(ExecutionResults status, string message)
        {
            this.status = status;
            this.message = message;
        }

        /// <summary>
        /// Object constructor that will accept Exception parameter.
        /// </summary>
        /// <param name="ex">Exception</param>
        public StoredFileExecResult(Exception ex)
        {
            status = ExecutionResults.Failed;
            message = ex.Message;
        }

   
        private string message;
        private ExecutionResults status;

        #region IExecResult Members

        ExecutionResults IExecResult.Status
        {
            get { return status; }
            set { status = value; }
        }

        string IExecResult.Message
        {
            get { return message; }
            set { message = value; }
        }

        #endregion
    }

    public class AddMetaDataExecResult : IAddMetaDataExecResult
    {
        public AddMetaDataExecResult()
        { }

        public AddMetaDataExecResult(int metaDataId)
        {
            this.metaDataID = metaDataId;
            this.message = "MetaData add successful.";
            this.status = ExecutionResults.Success;
        }

        public AddMetaDataExecResult(Exception ex)
        {
            this.status = ExecutionResults.Failed;
            this.message = ex.Message;
        }

        #region IAddMetaDataExecResult Members

        int metaDataID;
        int IAddMetaDataExecResult.MetaDataID
        {
            get
            {
                return metaDataID;
            }
            set
            {
                metaDataID = value;
            }
        }

        #endregion

        #region IExecResult Members

        ExecutionResults status;
        ExecutionResults IExecResult.Status
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
            }
        }

        string message;
        string IExecResult.Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }

        #endregion
    }

    public class UpdateMetaDataExecResult : IUpdateMetaDataExecResult
    {
        public UpdateMetaDataExecResult()
        {
        }

        public UpdateMetaDataExecResult(string message)
        {
            status = ExecutionResults.Success;
            this.message = message;
        }
        
        public UpdateMetaDataExecResult(Exception ex)
        {
            status = ExecutionResults.Failed;
            message = ex.Message;
        }

        #region IExecResult Members

        ExecutionResults status;
        ExecutionResults IExecResult.Status
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
            }
        }

        string message;
        string IExecResult.Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }

        #endregion
    }


    public class RemoveMetaDataExecResult : IRemoveMetaDataExecResult
    {
        public RemoveMetaDataExecResult()
        { }
        public RemoveMetaDataExecResult(string message)
        {
            this.status = ExecutionResults.Success;
            this.message = message;
        }

        public RemoveMetaDataExecResult(Exception ex)
        {
            this.status = ExecutionResults.Failed;
            this.message = ex.Message;
        }

        #region IExecResult Members

        ExecutionResults status;
        ExecutionResults IExecResult.Status
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
            }
        }

        string message;
        string IExecResult.Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }

        #endregion
    }

    public class DeleteMetaDataExecResult : IDeleteMetaDataExecResult
    {
        public DeleteMetaDataExecResult()
        { }
        public DeleteMetaDataExecResult(string message)
        {
            this.status = ExecutionResults.Success;
            this.message = message;
        }

        public DeleteMetaDataExecResult(Exception ex)
        {
            this.status = ExecutionResults.Failed;
            this.message = ex.Message;
        }

        #region IExecResult Members

        ExecutionResults status;
        ExecutionResults IExecResult.Status
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
            }
        }

        string message;
        string IExecResult.Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }

        #endregion
    }

    public class ReplicateExecResult : IReplicateExecResult
    {
        public ReplicateExecResult()
        { }

        public ReplicateExecResult(long phyFileId)
        {
            this.phyFileId = phyFileId;
            this.message = "Replicate successful.";
            this.status = ExecutionResults.Success;
        }

        public ReplicateExecResult(Exception ex)
        {
            this.status = ExecutionResults.Failed;
            this.message = ex.Message;
        }

        #region IReplicateExecResult Members

        long phyFileId;
        long IReplicateExecResult.PhyFileID
        {
            get
            {
                return phyFileId;
            }
            set
            {
                phyFileId = value;
            }
        }

        #endregion

        #region IExecResult Members

        ExecutionResults status;
        ExecutionResults IExecResult.Status
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
            }
        }

        string message;
        string IExecResult.Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }

        #endregion
    }

    public class GetPhysicalFilesExecResult : IGetPhysicalFilesExecResult
    {
        public GetPhysicalFilesExecResult()
        { }

        public GetPhysicalFilesExecResult(IList<PhysicalFileInfo> physicalFiles)
        {
            this.physicalFiles = physicalFiles;
            this.message = "Successful.";
            this.status = ExecutionResults.Success;
        }

        public GetPhysicalFilesExecResult(Exception ex)
        {
            this.status = ExecutionResults.Failed;
            this.message = ex.Message;
        }

        #region IGetReplicationInfoExecResult Members

        IList<PhysicalFileInfo> physicalFiles;
        IList<PhysicalFileInfo> IGetPhysicalFilesExecResult.PhysicalFiles
        {
            get
            {
                return physicalFiles;
            }
            set
            {
                physicalFiles = value;
            }
        }

        #endregion

        #region IExecResult Members

        ExecutionResults status;
        ExecutionResults IExecResult.Status
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
            }
        }

        string message;
        string IExecResult.Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }

        #endregion
    }

    public class GetStorageTypesExecResult : IGetStorageTypesExecResult
    {
        public GetStorageTypesExecResult()
        { }

        public GetStorageTypesExecResult(IList<StorageType> storageTypes)
        {
            this.storageTypes = storageTypes;
            this.message = "Successful.";
            this.status = ExecutionResults.Success;
        }

        public GetStorageTypesExecResult(Exception ex)
        {
            this.status = ExecutionResults.Failed;
            this.message = ex.Message;
        }

        #region IGetStorageTypesExecResult Members

        IList<StorageType> storageTypes;
        IList<StorageType> IGetStorageTypesExecResult.StorageTypes
        {
            get
            {
                return storageTypes;
            }
            set
            {
                storageTypes = value;
            }
        }

        #endregion

        #region IExecResult Members

        ExecutionResults status;
        ExecutionResults IExecResult.Status
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
            }
        }

        string message;
        string IExecResult.Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }

        #endregion
    }
    #endregion

}